/// File: VSLabAddin\addin.fs
/// 
/// Author: Antonio Cisternino (cisterni@di.unipi.it)
/// Author: Davide Morelli (morellid@di.unipi.it)
///   
/// ------------------------------------------------------------
/// Copyright (c) Microsoft Corporation.  All rights reserved.
/// 
/// The use and distribution terms for this software are 
/// contained in the file named license.txt, which can be found 
/// in the root of this distribution.
/// By using this software in any fashion, you are agreeing to 
/// be bound by the terms of this license.
///
/// You must not remove this notice, or any other, from this
/// software.
/// ------------------------------------------------------------

module VSLabAddin

open EnvDTE
open EnvDTE80
open EnvDTE90
open Extensibility
open Microsoft.Win32
open System.Windows.Forms
open System.Drawing
open System.IO

open System.Windows.Forms

open System.Reflection

//open Interop

// Splash screen version
let VSLabVersion = "VSLab ver. 1.3.0\nCopyright (c) Microsoft Corporation.  All rights reserved.\n\nDeveloped in collaboration with University of Pisa."

let debug msg =
    System.Diagnostics.EventLog.WriteEntry("Application", msg, System.Diagnostics.EventLogEntryType.Information)

/// <summary>
/// Creates a string with the correct registry key where the location of the vs lab dir is located
/// </summary>
let fetchVSLabDir () =
  use k = Registry.LocalMachine.OpenSubKey("SOFTWARE\\Unipi\\VSLab")
  let d = (k.GetValue("VSLabDir") :?> string)
  //debug (sprintf "Install dir: %s" d)
  d
    
/// <summary>
/// Converts an Image to a data structure usable in the Visual Studio Environment.
/// </summary>
type internal OleImageConverter() =
  inherit AxHost("59EE46BA-677D-4d20-BF10-8D8067CB8B33")
  
  /// <summary>
  /// Converts an Image to a data structure usable in the Visual Studio Environment.
  /// </summary>
  static member ConvertImage(img:#Image) =
    AxHost.GetIPictureFromPicture(img)
  
  static member GetImageMask(img:Bitmap) =
    let mask = img.Clone() :?> Bitmap
    for x = 0 to (img.Width - 1) do
      for y = 0 to (img.Height - 1) do
        let px = img.GetPixel(x, y)
        mask.SetPixel(x, y, if px = Color.Transparent || px.Name = "0" then Color.White else Color.Black)
    AxHost.GetIPictureFromPicture(mask)
  

/// <summary>
/// The VSLab Addin. 
/// This class is loaded when the Addin is started and takes care of 
/// managing the VSLab toolbar, 
/// registering the commands in the VS Environment, 
/// showing the Splash Screen, 
/// etc.
/// </summary>
type Addin() =

  let mutable appObj:DTE2 = null
  let mutable addInInst:AddIn = null
  let mutable lastSelected = "New File"
  let mutable comboHidden:Microsoft.VisualStudio.CommandBars.CommandBarComboBox = null
  let mutable hiddenList:string[] = [| |]
  
  let mutable sendToMenuItemFound = false
  let mutable sendToMenuItem:Microsoft.VisualStudio.CommandBars.CommandBarControl = null
  
  let mutable fsiToolWindow : Window option = None

  let ml_send (s:string) =
    match fsiToolWindow with
    | Some w ->
      let q = System.Text.RegularExpressions.Regex.Replace(s, @"([\#\(\)\^\~\^\{\}])", "{$1}")
      let nolines = q.Replace("\r\n", "{ENTER}")

      w.Activate()
      SendKeys.SendWait(nolines + " ")
      SendKeys.Flush()
      SendKeys.SendWait(";;")
      SendKeys.SendWait("{ENTER}")
    | None -> ()
  
  let mutable ctxtMenuInit = false
  
  let InitCtxtMenu () =
    if not ctxtMenuInit then
//      let bars = appObj.CommandBars :?> Microsoft.VisualStudio.CommandBars.CommandBars
//      let bar = bars.Item("Code Window")
//      for menubar in bar.Controls do
//        if menubar.Caption = "SendTo" then
//          sendToMenuItem <- menubar
//          sendToMenuItemFound <- true
//      if sendToMenuItemFound then    
//        sendToMenuItem.Visible <- true   
//      else
//        MessageBox.Show("Error loading the Code Window context menu item") |> ignore
      ctxtMenuInit <- true
  
  let initVSLab =
    let initcode = "#load @\"" + (fetchVSLabDir()) + "vslabstartup.fsx\""
    "let ___VS_PID = " + (System.Diagnostics.Process.GetCurrentProcess().Id.ToString()) + ";;\r\n"+initcode+";;"
  
  let findFSIToolWindow () =
    //debug "finding toolwindow..."
    let wnds = seq { for i in 1.. appObj.Windows.Count do yield appObj.Windows.[i] }
    try
      let w = (wnds |> Seq.find (fun w -> w.Caption = "F# Interactive"))
      Some w
    with
    | _ -> None

  let loadVSLabFSI() =
    //InitCtxtMenu()
    if fsiToolWindow.IsNone then
      fsiToolWindow <- findFSIToolWindow ()
      if fsiToolWindow.IsNone then
        appObj.ExecuteCommand("View.F#Interactive", "")
        fsiToolWindow <- findFSIToolWindow ()
      
      ml_send (initVSLab)        
  
  let VSLabSplashScreen() =
    let img = (fetchVSLabDir()) + "Splash.png"

    //let timeout = ref 10
    let timer = new Timer(Interval=5000)
    let fw, fh = (529, 320)
    let f = new Form(Text="VSLab", Width=fw, Height=fh, TopMost=true, FormBorderStyle=FormBorderStyle.None)
    let r = Screen.PrimaryScreen.WorkingArea
    let im = Image.FromFile(img)
    f.Paint.Add(fun evt ->
      let g = evt.Graphics
      g.DrawImage(im, 0, 0)
      g.DrawString(VSLabVersion, f.Font, Brushes.White, new RectangleF(22.0f, 170.0f, 180.0f, 310.0f))
    )
    timer.Tick.Add(fun _ ->
      //f.Invalidate()
//      timeout := !timeout - 1
//      if !timeout = 0 then
//        timer.Enabled <- false
        im.Dispose()
        f.Dispose()
    )
    f.Show()
    f.Left <- (r.Width - fw) / 2
    f.Top <- (r.Height - fh) / 2
    timer.Start()

  let initVSLabAddin (app:obj) (addInInstance:obj) =
    //debug "Initializing VSLab"
    let command (cmds:Commands2) (name:string) =
      try
        cmds.Item("VSLabAddin+Addin." + name, 0)
      with
       | _ -> null

    addInInst <- (addInInstance :?> AddIn)
    appObj <- (app :?> DTE2)

    let cmds = appObj.Commands :?> Commands2
    let mutable (cguids:obj[]) = null

    //debug "Creating StartVSLab command..."
    if command cmds "StartVSLab" = null then
      let cmd = cmds.AddNamedCommand2(addInInst, "StartVSLab", "Quick start VSLab", "Quick start VSLab", false, 1, &cguids, int(vsCommandStatus.vsCommandStatusSupported ||| vsCommandStatus.vsCommandStatusEnabled), int(vsCommandStyle.vsCommandStylePictAndText), vsCommandControlType.vsCommandControlTypeButton)
      cmd.Bindings <- "Global::shift+alt+v"


  let startVSLab () =
    let command (cmds:Commands2) (name:string) =
      try
        cmds.Item("VSLabAddin+Addin." + name, 0)
      with
       | _ -> null
    //debug "Showing splash screen..."
    VSLabSplashScreen()

(*
#I "C:\Program Files\Microsoft Visual Studio 9.0\Common7\IDE\PublicAssemblies"
#I "C:\Program Files\Microsoft.NET\Primary Interop Assemblies"
#I "C:\Programmi\Microsoft.NET\Primary Interop Assemblies"
#r @"EnvDTE.dll"
#r @"EnvDTE80.dll"
#r @"EnvDTE90.dll"
#r @"stdole.dll"
#r @"Microsoft.VisualStudio.CommandBars.dll"
#r @"Extensibility.dll"
#r @"FSharp.VS.FSI.dll"
 let appObj = System.Runtime.InteropServices.Marshal.GetActiveObject("VisualStudio.DTE") :?> EnvDTE80.DTE2
 let wnds = appObj.Windows :?> EnvDTE80.Windows2
 wnds.Count
 let wnd = wnds.Item(3) :?> EnvDTE80.Window2
 for i in 1..12 do printfn "%s" (wnds.Item(i).Caption)
 wnd.Caption
 wnd.HWnd
 (wnd.LinkedWindowFrame :> EnvDTE.Window).HWnd
 (appObj.ToolWindows :?> EnvDTE80.ToolWindows).GetToolWindow("F# Interactive")
 wnd.GetType()
 #r @"c:\FSharp.VS.FSI.dll"
 let a = System.Reflection.Assembly.LoadFile(@"c:\FSharp.VS.FSI.dll")
 let t = (a.GetTypes() |> Array.filter (fun t -> t.Name = "FsiToolWindow")).[0]
 open System.Reflection
 wnd
 let m = Array.find (fun (m:System.Reflection.MethodInfo) -> m.Name.StartsWith("executeTextNoHistory")) (t.GetMethods(BindingFlags.Public ||| BindingFlags.NonPublic ||| BindingFlags.Instance))
 m.Invoke(wnd2, [| "2 + 2;;" |])
 wnd.GetType().GetMethods()

(wnd :?> Microsoft.VisualStudio.FSharp.Interactive.FsiToolWindow)
let wnd2 =(wnd :?> EnvDTE80.Window2)
let addInInst = appObj.AddIns.Item(1)
 *)
    let cmds = appObj.Commands :?> Commands2
    let mutable (cguids:obj[]) = null

// for cc in cmds do if cc.Name.StartsWith("VSLabAddin") then cc.Delete();;
// for cc in cmds do if cc.Name = "VSLabAddin+Addin.SendTo" then cc.Delete();;
(*
 let mutable sendToCmd = appObj.Commands.Item("VSLabAddin+Addin.SendTo", -1)
 *)

    let bars = appObj.CommandBars :?> Microsoft.VisualStudio.CommandBars.CommandBars
    let bar = bars.Item("Code Window")

//    debug "Creating Send to..."
//    if command cmds "SendTo" = null then
//      // Context menu
//      let sendToCmd = cmds.AddNamedCommand2(addInInst, "SendTo", "SendTo", "Sends selected text to a source file", true, 59, &cguids, int(vsCommandStatus.vsCommandStatusSupported ||| vsCommandStatus.vsCommandStatusEnabled), int(vsCommandStyle.vsCommandStyleComboNoAutoComplete), vsCommandControlType.vsCommandControlTypeDropDownCombo)
//      sendToCmd.AddControl(bar, 1) |> ignore
//      let sendToBar = bar.Controls.Item(1)
//      sendToBar.Visible <- false
//
//    debug "adding sendto..."
//    for menubar in bar.Controls do
//      if menubar.Caption = "SendTo" then
//        sendToMenuItem <- menubar
//        sendToMenuItemFound <- true
//    sendToMenuItem.Visible <- false
    
    Application.DoEvents()

    debug "create the toolbar"
    // Create the toolbar
    let toolbar = try bars.Item("VSLab") with _ -> bars.Add("VSLab", 1, System.Type.Missing, true)
    toolbar.Visible <- true

    Application.DoEvents()

    debug "Show VSLab"
    let showCmd = 
           if command cmds "ShowVSLab" = null then
             cmds.AddNamedCommand2(addInInst, "ShowVSLab", "Show/Hide VSLab window", "Show/Hide VSLab window", false, 1, &cguids, int(vsCommandStatus.vsCommandStatusSupported ||| vsCommandStatus.vsCommandStatusEnabled), int(vsCommandStyle.vsCommandStylePictAndText), vsCommandControlType.vsCommandControlTypeButton)
           else
             command cmds "ShowVSLab"

    Application.DoEvents()
    
    debug "Hidden Viewlet"
    let hiddenViewlets =
           if command cmds "HiddenViewlets" = null then
             cmds.AddNamedCommand2(addInInst, "HiddenViewlets", "Hidden Viewlets", "List of hidden viewlets", true, 59, &cguids, int(vsCommandStatus.vsCommandStatusSupported ||| vsCommandStatus.vsCommandStatusEnabled), int(vsCommandStyle.vsCommandStyleComboNoAutoComplete), vsCommandControlType.vsCommandControlTypeDropDownCombo)
           else
             command cmds "HiddenViewlets"

    Application.DoEvents()

    debug "Send init VSLab"
    let initVSLab =
           if command cmds "SendInitVSLab" = null then
             cmds.AddNamedCommand2(addInInst, "SendInitVSLab", "Send init to VSLab", "Send init to VSLab, useful when F# interactive is restarted", false, 1, &cguids, int(vsCommandStatus.vsCommandStatusSupported ||| vsCommandStatus.vsCommandStatusEnabled), int(vsCommandStyle.vsCommandStylePictAndText), vsCommandControlType.vsCommandControlTypeButton)
           else
             command cmds "SendInitVSLab"

    Application.DoEvents()

    debug "Show conf"
    let showConf =
           if command cmds "ShowConfiguration" = null then
             cmds.AddNamedCommand2(addInInst, "ShowConfiguration", "Show configuration panel", "Show VSLab configuration panel", false, 1, &cguids, int(vsCommandStatus.vsCommandStatusSupported ||| vsCommandStatus.vsCommandStatusEnabled), int(vsCommandStyle.vsCommandStylePictAndText), vsCommandControlType.vsCommandControlTypeButton)
           else
             command cmds "ShowConfiguration"

    Application.DoEvents()

    if command cmds "PopulateHiddenViewletsList" = null then
      cmds.AddNamedCommand2(addInInst, "PopulateHiddenViewletsList", "Internal command", "Not for external use", false, 1, &cguids, int(vsCommandStatus.vsCommandStatusSupported ||| vsCommandStatus.vsCommandStatusEnabled), int(vsCommandStyle.vsCommandStylePictAndText), vsCommandControlType.vsCommandControlTypeButton) |> ignore

    if command cmds "FSIExec" = null then
        cmds.AddNamedCommand2(addInInst, "FSIExec", "Internal command", "Not for external use", false, 1, &cguids, int(vsCommandStatus.vsCommandStatusSupported ||| vsCommandStatus.vsCommandStatusEnabled), int(vsCommandStyle.vsCommandStylePictAndText), vsCommandControlType.vsCommandControlTypeButton) |> ignore

    Application.DoEvents()

    let assignIcon (b:Microsoft.VisualStudio.CommandBars.CommandBarButton) (img:string) =
      debug (sprintf "Assign icon %s" img)
      b.Style <- Microsoft.VisualStudio.CommandBars.MsoButtonStyle.msoButtonIcon
      let icon = Bitmap.FromFile(img) :?> Bitmap
      b.Picture <- (OleImageConverter.ConvertImage(icon) :?> stdole.StdPicture)
      //b.Mask <- (OleImageConverter.GetImageMask(icon) :?> stdole.StdPicture)
      debug (sprintf "Assigned icon %s" img)

    loadVSLabFSI() // Introduced for VS2010

    Application.DoEvents()
    
    debug "Adding Hide VSLab"
    let showBtn = showCmd.AddControl(toolbar, toolbar.Controls.Count + 1) :?> Microsoft.VisualStudio.CommandBars.CommandBarButton
    assignIcon showBtn ((fetchVSLabDir()) + "Hide.png")

    Application.DoEvents()

    debug "Adding Reset"
    let initBtn = initVSLab.AddControl(toolbar, toolbar.Controls.Count + 1)  :?> Microsoft.VisualStudio.CommandBars.CommandBarButton
    assignIcon initBtn ((fetchVSLabDir()) + "Reset.png")

    Application.DoEvents()

    debug "Adding Hidden viewlets"
    comboHidden <- (hiddenViewlets.AddControl(toolbar, toolbar.Controls.Count + 1) :?> Microsoft.VisualStudio.CommandBars.CommandBarComboBox)

    Application.DoEvents()

    debug "Adding Configure"
    let confBtn = showConf.AddControl(toolbar, toolbar.Controls.Count + 1)  :?> Microsoft.VisualStudio.CommandBars.CommandBarButton
    assignIcon confBtn ((fetchVSLabDir()) + "Conf.png")  
  
  interface IDTExtensibility2 with
    /// <summary>
    /// VSLab is quitting.
    /// </summary>
    /// <param name="args"> arguments not used</param>
    member x.OnBeginShutdown(args) =
      ()//ml_send ("VSLab.Viewlets.Quit()")

    /// <summary>
    /// VSLab is being updated
    /// </summary>
    /// <param name="args"> arguments not used</param>
    member x.OnAddInsUpdate(args) =
      loadVSLabFSI()

    /// <summary>
    /// VSLab has succesfully started
    /// </summary>
    /// <param name="args"> arguments not used</param>
    member x.OnStartupComplete(args) = ()

    /// <summary>
    /// VSLab is being closed
    /// </summary>
    /// <param name="arg1"> arguments not used</param>
    /// <param name="arg2"> arguments not used</param>
    member x.OnDisconnection(arg1, arg2) = ()

    /// <summary>
    /// VSLab is starting, this function shows the splash screen
    /// </summary>
    /// <param name="app"> the DTE2 instance</param>
    /// <param name="conmode"> argument not used</param>
    /// <param name="addInInstance"> the addin instance</param>
    /// <param name="custom"> argument not used</param>
    member x.OnConnection(app, conmode, addInInstance, custom) = 
      initVSLabAddin app addInInstance
      
  interface IDTCommandTarget with
    /// <summary>
    /// A command registered by VSLab has been invoked
    /// </summary>
    /// <param name="cmdName"> the name of the executed command</param>
    /// <param name="execOption"> only the vsCommandExecOption.vsCommandExecOptionDoDefault is handled</param>
    /// <param name="variantIn"> input parameter, used by the VSLab menu bar and by the Code Window context menu VSLab "SendTo" combo box</param>
    /// <param name="variantOut"> output parameter, used by the VSLab menubar and by the Code Window context menu VSLab "SendTo" combo box</param>
    /// <param name="handled"> output parameter, true if the command is handled</param>
    member x.Exec(cmdName,execOption,variantIn,variantOut,handled) = 
      handled <- false
      if execOption = vsCommandExecOption.vsCommandExecOptionDoDefault then
        match cmdName with
        | "VSLabAddin+Addin.StartVSLab" -> 
          startVSLab()
          loadVSLabFSI()
          handled <- true
//        | "VSLabAddin+Addin.SendTo" ->
//          if variantIn <> null then
//            let selectedText = variantIn :?> string
//            let currDoc = appObj.ActiveDocument.Object("TextDocument") :?> TextDocument
//            let textToSend = currDoc.Selection.Text
//            if selectedText = "New File" then
//              try
//                let newItem = appObj.ItemOperations.AddNewItem(@"F# Source Files\F# Source File", "")
//                let newWnd = newItem.Open(EnvDTE.Constants.vsViewKindCode)
//                newWnd.Activate()
//                let tdoc = appObj.ActiveDocument.Object("TextDocument") :?> TextDocument
//                let ep = tdoc.EndPoint.CreateEditPoint()
//                ep.Insert(textToSend)
//                appObj.ActiveDocument.Save(appObj.ActiveDocument.FullName) |> ignore
//              with
//                | err -> MessageBox.Show(err.ToString()) |> ignore
//            else
//              try
//                // cerco tra i ProjectItem quello col nome corrispondente
//                for i in appObj.ActiveDocument.ProjectItem.Collection do
//                  if i.Name = selectedText then
//                    let newWnd = i.Open(EnvDTE.Constants.vsViewKindCode)
//                    newWnd.Activate()
//                    let tdoc = appObj.ActiveDocument.Object("TextDocument") :?> TextDocument
//                    let ep = tdoc.EndPoint.CreateEditPoint()
//                    ep.Insert(textToSend)
//              with
//                | err -> MessageBox.Show(err.ToString()) |> ignore
//
//            lastSelected <- selectedText
//          else
//            variantOut <- (lastSelected :> obj)
//          handled <- true
//        | "VSLabAddin+Addin.SendTo_1" ->         
//          let mutable files = [ "New File" ]
//          for i in appObj.ActiveDocument.ProjectItem.Collection do
//            if i.Kind = EnvDTE.Constants.vsProjectItemKindPhysicalFile && Path.GetExtension(i.Name.ToLower()) <> ".vslab" then
//              files <- List.append [ i.Name ] files
//          variantOut <- ((List.toArray files) :> obj)
//           
//          handled <- true
        | "VSLabAddin+Addin.ShowVSLab" ->
          appObj.ExecuteCommand("View.F#Interactive", "")
        | "VSLabAddin+Addin.HiddenViewlets" ->
          if variantIn <> null then
            let selectedText = (variantIn :?> string)
            ml_send("VSLab.Viewlets.ShowViewlet(\""+selectedText+"\")")
          handled <- true
        | "VSLabAddin+Addin.HiddenViewlets_1" ->
          variantOut <- (hiddenList :> obj)
          handled <- true
        | "VSLabAddin+Addin.PopulateHiddenViewletsList" ->
          let arg = (variantIn :?> string)
          hiddenList <- arg.Split([| "#__#" |], System.StringSplitOptions.None)
          handled <- true
        | "VSLabAddin+Addin.FSIExec" ->
          let arg = (variantIn :?> string)
          ml_send(arg)
          handled <- true
        | "VSLabAddin+Addin.SendInitVSLab" ->
          ml_send (initVSLab)
          handled <- true
        | "VSLabAddin+Addin.ShowConfiguration" ->
          ml_send ("VSLab.Configuration.VSLabConfigurationDialog()")
          handled <- true
        | _ -> ()
        
    /// <summary>
    /// The availability of a command registered by VSLab is being checked.
    /// </summary>        
    /// <param name="cmdName"> the name of the command</param>
    /// <param name="neededText"> query type</param>
    /// <param name="statusOpt"> output parameter, enables or disables the command</param>
    /// <param name="commandText"> output parameter, the tool tip text</param>
    member x.QueryStatus(cmdName,neededText,statusOpt,commandText) = 
      // debug (sprintf "Query status requested for command %s" cmdName)
      if neededText = vsCommandStatusTextWanted.vsCommandStatusTextWantedNone then
        match cmdName with
        | "VSLabAddin+Addin.StartVSLab" -> 
          statusOpt <- vsCommandStatus.vsCommandStatusSupported ||| vsCommandStatus.vsCommandStatusEnabled
//        | "VSLabAddin+Addin.SendTo" ->
//          //statusOpt <- vsCommandStatus.vsCommandStatusSupported ||| vsCommandStatus.vsCommandStatusEnabled
//          //statusOpt <- vsCommandStatus.vsCommandStatusInvisible
//          let sel = appObj.ActiveDocument.Selection :?> TextSelection
//          let projExt = Path.GetExtension(appObj.ActiveWindow.Project.FileName) 
//          if (fsiToolWindow.IsNone) || (projExt <> ".fsproj") then
//            //sendToMenuItem.Visible <- false
//            statusOpt <- vsCommandStatus.vsCommandStatusInvisible
//          else
//            //sendToMenuItem.Visible <- true
//            statusOpt <- 
//              if sel.Text.Length > 0 then 
//                vsCommandStatus.vsCommandStatusSupported ||| vsCommandStatus.vsCommandStatusEnabled
//              else 
//                vsCommandStatus.vsCommandStatusUnsupported
//          (*
//          statusOpt <- 
//            if not fsiLoaded then
//              vsCommandStatus.vsCommandStatusInvisible
//            elif sel.Text.Length > 0 then 
//              vsCommandStatus.vsCommandStatusSupported ||| vsCommandStatus.vsCommandStatusEnabled;
//            else 
//              vsCommandStatus.vsCommandStatusUnsupported *)
        | "VSLabAddin+Addin.ShowVSLab" ->
          if fsiToolWindow.IsNone then
            statusOpt <- vsCommandStatus.vsCommandStatusInvisible
          else
            statusOpt <- vsCommandStatus.vsCommandStatusSupported ||| vsCommandStatus.vsCommandStatusEnabled
        | "VSLabAddin+Addin.HiddenViewlets" ->
          if fsiToolWindow.IsNone then
            statusOpt <- vsCommandStatus.vsCommandStatusInvisible
          else
            statusOpt <- vsCommandStatus.vsCommandStatusSupported ||| vsCommandStatus.vsCommandStatusEnabled
        | "VSLabAddin+Addin.SendInitVSLab" ->
          if fsiToolWindow.IsNone then
            statusOpt <- vsCommandStatus.vsCommandStatusInvisible
          else
            statusOpt <- vsCommandStatus.vsCommandStatusSupported ||| vsCommandStatus.vsCommandStatusEnabled
        | "VSLabAddin+Addin.ShowConfiguration" ->
          if fsiToolWindow.IsNone then
            statusOpt <- vsCommandStatus.vsCommandStatusInvisible
          else
            statusOpt <- vsCommandStatus.vsCommandStatusSupported ||| vsCommandStatus.vsCommandStatusEnabled
        | "VSLabAddin+Addin.PopulateHiddenViewletsList" ->
          statusOpt <- vsCommandStatus.vsCommandStatusSupported ||| vsCommandStatus.vsCommandStatusEnabled
        | "VSLabAddin+Addin.FSIExec" ->
          statusOpt <- vsCommandStatus.vsCommandStatusSupported ||| vsCommandStatus.vsCommandStatusEnabled
        | _ -> ()
      elif neededText = vsCommandStatusTextWanted.vsCommandStatusTextWantedName then
        match cmdName with
        | "VSLabAddin+Addin.StartVSLab" -> 
          commandText <- ("Start VSLab" :> obj)
//        | "VSLabAddin+Addin.SendTo" -> 
//          commandText <- ("Send selection to source file" :> obj)
        | "VSLabAddin+Addin.ShowVSLab" ->
          commandText <- ("Shows or hide the VSLab window" :> obj)
        | "VSLabAddin+Addin.HiddenViewlets" ->
          commandText <- ("List of the hidden viewlets" :> obj)
        | "VSLabAddin+Addin.SendInitVSLab" ->
          commandText <- ("Send init to VSLab" :> obj)
        | "VSLabAddin+Addin.ShowConfiguration" ->
          commandText <- ("Show VSLab configuration" :> obj)
        | "VSLabAddin+Addin.PopulateHiddenViewletsList" ->
          commandText <- ("Internal" :> obj)
        | "VSLabAddin+Addin.FSIExec" ->
          commandText <- ("Internal" :> obj)
        | _ -> ()
      

